Telegram Group & Telegram Channel
🐍 Ошибка с изменяемыми значениями по умолчанию»**

🎯 Цель: Найти и объяснить баг, который не вызывает исключений, но ломает логику приложения

📍 Ситуация:

У тебя есть функция, которая логирует события с метаданными. По умолчанию метаданные можно не передавать:


def log_event(event, metadata={}):
metadata["event"] = event
print(metadata)


На первый взгляд — всё работает. Но при многократных вызовах функции происходит что-то странное:


log_event("start")
log_event("stop")
log_event("error", {"code": 500})
log_event("retry")


👀 Вывод:

{'event': 'start'}
{'event': 'stop'}
{'code': 500, 'event': 'error'}
{'code': 500, 'event': 'retry'}


🔍 Что пошло не так? Почему code: 500 появляется там, где его быть не должно?

🧩 Задача:

1. Найди и объясни источник бага
2. Почему Python не выбрасывает ошибку?
3. Как проверить, что дефолтный аргумент сохраняет состояние между вызовами?
4. Как это исправить безопасно и "по питоновски"?
5. Где ещё может проявиться аналогичный эффект?


🛠 Разбор и решение:

🔸 Причина:
Изменяемое значение (`dict`) используется как значение по умолчанию.
В Python значения по умолчанию вычисляются один раз при определении функции, а не при каждом вызове.

То есть metadata={} создаётся один раз и сохраняется между вызовами, если параметр не передан.

🔸 Проверка:

def f(d={}):
print(id(d))
d["x"] = 1
print(d)

f()
f()

Вы увидишь одинаковые id(d) — значит, используется тот же объект.

🔸 Решение (правильный способ):

def log_event(event, metadata=None):
if metadata is None:
metadata = {}
metadata["event"] = event
print(metadata)


Теперь при каждом вызове создаётся новый словарь, и code: 500 не "протекает" в следующие вызовы.

🔸 Где ещё встречается:
- Списки: items=[]
- Множества: visited=set()
- Объекты пользовательских классов

📌 Вывод:
Изменяемые значения по умолчанию — одна из самых частых ошибок в Python. Она не вызывает исключений, но может незаметно повредить данные. Всегда используй None + инициализацию внутри функции для изменяемых типов.



@Python_Community_ru



tg-me.com/Python_Community_ru/2631
Create:
Last Update:

🐍 Ошибка с изменяемыми значениями по умолчанию»**

🎯 Цель: Найти и объяснить баг, который не вызывает исключений, но ломает логику приложения

📍 Ситуация:

У тебя есть функция, которая логирует события с метаданными. По умолчанию метаданные можно не передавать:


def log_event(event, metadata={}):
metadata["event"] = event
print(metadata)


На первый взгляд — всё работает. Но при многократных вызовах функции происходит что-то странное:


log_event("start")
log_event("stop")
log_event("error", {"code": 500})
log_event("retry")


👀 Вывод:

{'event': 'start'}
{'event': 'stop'}
{'code': 500, 'event': 'error'}
{'code': 500, 'event': 'retry'}


🔍 Что пошло не так? Почему code: 500 появляется там, где его быть не должно?

🧩 Задача:

1. Найди и объясни источник бага
2. Почему Python не выбрасывает ошибку?
3. Как проверить, что дефолтный аргумент сохраняет состояние между вызовами?
4. Как это исправить безопасно и "по питоновски"?
5. Где ещё может проявиться аналогичный эффект?


🛠 Разбор и решение:

🔸 Причина:
Изменяемое значение (`dict`) используется как значение по умолчанию.
В Python значения по умолчанию вычисляются один раз при определении функции, а не при каждом вызове.

То есть metadata={} создаётся один раз и сохраняется между вызовами, если параметр не передан.

🔸 Проверка:

def f(d={}):
print(id(d))
d["x"] = 1
print(d)

f()
f()

Вы увидишь одинаковые id(d) — значит, используется тот же объект.

🔸 Решение (правильный способ):

def log_event(event, metadata=None):
if metadata is None:
metadata = {}
metadata["event"] = event
print(metadata)


Теперь при каждом вызове создаётся новый словарь, и code: 500 не "протекает" в следующие вызовы.

🔸 Где ещё встречается:
- Списки: items=[]
- Множества: visited=set()
- Объекты пользовательских классов

📌 Вывод:
Изменяемые значения по умолчанию — одна из самых частых ошибок в Python. Она не вызывает исключений, но может незаметно повредить данные. Всегда используй None + инициализацию внутри функции для изменяемых типов.



@Python_Community_ru

BY Python Community


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/Python_Community_ru/2631

View MORE
Open in Telegram


Python Community Telegram | DID YOU KNOW?

Date: |

For some time, Mr. Durov and a few dozen staffers had no fixed headquarters, but rather traveled the world, setting up shop in one city after another, he told the Journal in 2016. The company now has its operational base in Dubai, though it says it doesn’t keep servers there.Mr. Durov maintains a yearslong friendship from his VK days with actor and tech investor Jared Leto, with whom he shares an ascetic lifestyle that eschews meat and alcohol.

However, analysts are positive on the stock now. “We have seen a huge downside movement in the stock due to the central electricity regulatory commission’s (CERC) order that seems to be negative from 2014-15 onwards but we cannot take a linear negative view on the stock and further downside movement on the stock is unlikely. Currently stock is underpriced. Investors can bet on it for a longer horizon," said Vivek Gupta, director research at CapitalVia Global Research.

Python Community from tw


Telegram Python Community
FROM USA